package com.atguigu.tingshu.user.service.impl;
import java.util.Date;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaSigner;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.security.interfaces.RSAPrivateKey;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	WxMaService wxMaService;

	@Autowired
	StringRedisTemplate redisTemplate;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	@Autowired
	RSAPrivateKey rsaPrivateKey;

	@Autowired
	RabbitService rabbitService;

	@Override
	public Map<String, String> wxLogin(String code) {
		try {

			WxMaUserService userService = wxMaService.getUserService();
			WxMaJscode2SessionResult sessionInfo = userService.getSessionInfo(code);
			//获取openid用户唯一表示
			String openid = sessionInfo.getOpenid();
			if (StringUtils.isEmpty(openid)){
				throw new GuiguException(201,"登录调用异常");
			}

			LambdaQueryWrapper<UserInfo>wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(UserInfo::getWxOpenId,openid);
			UserInfo userInfo = userInfoMapper.selectOne(wrapper);
			if (userInfo == null){
				userInfo = new UserInfo();
				userInfo.setWxOpenId(openid);
				userInfo.setNickname("测试用户");
				userInfo.setIsVip(0);
				userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
				if (!save(userInfo)) {
					throw new GuiguException(201, "注册失败");
				}
				//throw new GuiguException(ResultCodeEnum.USER_INFO_NULL);
				//账户余额
				rabbitService.sendMessage(MqConst
						.EXCHANGE_ACCOUNT,MqConst
						.ROUTING_USER_REGISTER,userInfo.getId().toString());




			}
			//reids存储userInfo
			long time = System.currentTimeMillis() + 1000 * 60 * 60 * 23;
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("id",userInfo.getId()+"");
			jsonObject.put("time",String.valueOf(time));
			Jwt jwt = JwtHelper.encode(jsonObject.toJSONString(), new RsaSigner(rsaPrivateKey));//构建一个jwt的载荷
			//得到载荷
			String token = jwt.getEncoded();

			stringRedisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX+userInfo.getId(),
					token,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
			//返回前端map
			Map<String,String> map = new HashMap<>();
			map.put("token",token);
			return map;
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}

	}

	@Override
	public UserInfoVo getUserInfo(Long userId) {
		UserInfo userInfoById = getById(userId);
		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setId(userId);
		userInfoVo.setWxOpenId(userInfoById.getWxOpenId());
		userInfoVo.setNickname(userInfoById.getNickname());
		userInfoVo.setAvatarUrl(userInfoById.getAvatarUrl());
		userInfoVo.setIsVip(userInfoById.getIsVip());
		userInfoVo.setVipExpireTime(userInfoById.getVipExpireTime());
		return userInfoVo;
	}

	@Override
	public void updateUser(UserInfoVo userInfoVo, Long userId) {
		UserInfo userInfo = userInfoMapper.selectById(userId);
		if (userInfo == null){
			throw new GuiguException(201,"不存在这个用户");
		}
		userInfoVo.setAvatarUrl(userInfoVo.getAvatarUrl());
		userInfoVo.setNickname(userInfo.getNickname());
		if (!updateById(userInfo)){
			throw new GuiguException(201,"修改失败");
		}
	}

	@Override
	public UserInfo getUserInfoByIdrpc(Long userId) {
		UserInfo userInfo = userInfoMapper.selectById(userId);
		return userInfo;
	}
}
